package edu.qichen.onlineBlog.framework;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import edu.qichen.onlineBlog.framework.utils.ipUtils;
import edu.qichen.onlineBlog.log.pojo.LoginLog;
import edu.qichen.onlineBlog.log.pojo.Syslog;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 功能:
 * 作者:程序员欧阳子韩
 * 日期:2024/6/23 10:40
 */
@Aspect
@Component
@EnableAsync
@Slf4j
public class LoginLogAspect {
    private String requestPath = null; // 请求地址

    private String user = null; // 登录用户

    private HttpServletRequest request = null;//请求

    @Resource
    LoginQueue loginQueue;

    /**
     * 注解的位置
     */
    @Pointcut("@annotation(edu.qichen.onlineBlog.framework.LoginAnnotation)")
    public void loginPointCut() {
    }

    /**
     * 前置通知  方法调用前触发   记录开始时间,从session中获取操作人
     *
     * @param joinPoint -
     */

    @Before(value = "loginPointCut()")
    public void before(JoinPoint joinPoint) {
    }

    /**
     * 获取入参方法参数
     *
     * @param joinPoint -
     * @return -
     */

    public Map<String, Object> getNameAndValue(JoinPoint joinPoint) {
        Map<String, Object> param = new HashMap<>();
        Object[] paramValues = joinPoint.getArgs();
        String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
        for (int i = 0; i < paramNames.length; i++) {
            if (paramValues[i] instanceof Integer || paramValues[i] instanceof String) {
                param.put(paramNames[i], paramValues[i]);
            }
        }
        return param;
    }

    /**
     * 后置通知    方法调用后触发
     *
     * @param joinPoint -
     */
    @After(value = "loginPointCut()")
    public void after(JoinPoint joinPoint) {
        HttpServletRequest request = getHttpServletRequest();

        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();

        Class<?> targetClass = null;
        try {
            targetClass = Class.forName(targetName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        Method[] methods = targetClass.getMethods();

        Class<?>[] clazzs;

        // 获取登录Ip
        String ipAddr = ipUtils.getIpAddr(request);

        // 登录地址
        if ("0:0:0:0:0:0:0:1".equals(ipAddr)) {
            ipAddr = "127.0.0.1";
        } else if (ipUtils.internalIp(ipAddr)) {
            requestPath = "内部Ip";
        } else {
            if ("127.0.0.1".equals(ipAddr)) {
                requestPath = "本机地址";
            } else {
                String url = "http://ip-api.com/json/" + ipAddr  + "?lang=zh-CN";
                String result = HttpUtil.get(url);
                JSONObject jsonObject = JSONUtil.parseObj(result);
                String country = jsonObject.getStr("country");
                String city = jsonObject.getStr("city");
                requestPath = city + " " + country;
            }
        }


        HttpSession session = request.getSession();
        Object username = session.getAttribute("username");
        if (!(username instanceof String)) {
            return; // 如果没有获取到合法的用户名，直接结束方法
        }
        String user = username.toString();

        // 创建并填充LoginLog对象
        LoginLog log = new LoginLog();
        log.setLoginUser(user);
        log.setLoginIp(ipAddr);
        log.setLoginLocation(requestPath);

        loginQueue.add(log);
    }


    /**
     * 获取request
     *
     * @return -
     */
    public HttpServletRequest getHttpServletRequest() {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        return request;
    }

    /**
     * @param joinPoint -
     * @return 环绕通知
     * @throws Throwable -
     */
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        return null;
    }

    /**
     * 异常通知
     *
     * @param joinPoint -
     */
    public void throwing(JoinPoint joinPoint) {
        log.error("异常通知");
    }
}
